﻿using System;
using System.Collections;
using Unity.VisualScripting;
using UnityEngine;


public class Stone : MonoBehaviour, IDamageable
{
    #region Unity方法
    private void Awake()
    {
        InitPhysics();
    }

    private void Update()
    {
        if (_rolling) 
        {
            if (HasThingFont()) 
            {
                Stop();
            }
        }
        if (!OnGrounded)
        {
            Fall();
        }
    }
    private void OnDrawGizmos()
    {
        DrawSensorLine();
    }

    #endregion

    #region 物理系统
    private Rigidbody2D _rb;
    public void InitPhysics() 
    {
        _rb = GetComponent<Rigidbody2D>();
    }
    #endregion

    #region 检测器
    [SerializeField] private Transform _groundSensor;
    [SerializeField] private float _groundRadius;
    [SerializeField] private LayerMask _groundMask;

    public bool OnGrounded => Physics2D.OverlapCircle(_groundSensor.position, _groundRadius, _groundMask);


    [SerializeField] private Transform _fontSensor;
    [SerializeField] private float _fontRadius;
    [SerializeField] private LayerMask _fontMask;
    public bool HasThingFont() { 

        var raycastHit2D=Physics2D.Linecast(_fontSensor.position, new Vector2(_fontSensor.position.x + _direction * _fontRadius, _fontSensor.position.y), _fontMask);
        if (raycastHit2D.collider==null) 
        {
            return false;
        }
        if (raycastHit2D.collider.gameObject == this.gameObject) 
        {
            return false;
        }
        else 
        {
            return true;
        }
    }

    [SerializeField] private Transform _downSensor;
    [SerializeField] private float _downRadius;
    [SerializeField] private LayerMask _downMask;
    public bool HasThingDown => Physics2D.Linecast(_downSensor.position, new Vector2(_downSensor.position.x, _downSensor.position.y - _downRadius), _downMask);

    private void DrawSensorLine()
    {
        Gizmos.DrawWireSphere(_groundSensor.position, _groundRadius);
        Gizmos.DrawLine(_fontSensor.position, _fontSensor.position - transform.right * _fontRadius);
        Gizmos.DrawLine(_downSensor.position, new Vector2(_downSensor.position.x, _downSensor.position.y - _downRadius));
    }

    #endregion
    [SerializeField] private float _pushSpeed;
    [SerializeField] private float _pushTime;
    /// <summary>
    ///推
    /// </summary>
    public void Push(int dir) 
    {
        _rb.velocity = new Vector2(dir*_pushSpeed,0);
        StartCoroutine(StopPush());
    }

    private IEnumerator StopPush()
    {
        yield return new WaitForSeconds(_pushTime);
        _rb.velocity = Vector2.zero;
    }

    #region 滚动

    private bool _rolling=false;
    [SerializeField]private float _rollSpeed = 10;
    public void Roll() 
    {
        _rolling=true;
        _rb.velocity = new Vector2(_direction*_rollSpeed,0);
    }

    #endregion

    [SerializeField] private float _fallSpeed = 10;
    /// <summary>
    /// 下坠
    /// </summary>

    public void Fall()
    {
        _rolling = false;
        _rb.velocity = new Vector2(0, -_fallSpeed);
        StartCoroutine(DetectionGroundCoro());
    }

    private IEnumerator DetectionGroundCoro()
    {
        yield return new WaitUntil(()=>OnGrounded);
        _rb.velocity = Vector2.zero;
    }

    /// <summary>
    /// 停止
    /// </summary>
    private void Stop()
    {
        _rolling = false;
        _rb.velocity = Vector2.zero;
    }

    //受到攻击
    private int _direction;

    public void TakeDamage(AttackDetail detail)
    {
        Debug.Log("击中");
        _direction = detail.Direction;
        Debug.Log(_direction);
        Roll();
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
     
        if(collision.gameObject.CompareTag("Player")|| collision.gameObject.CompareTag("Enemy")) 
        {
            if (_rolling) 
            {
               var damageable= collision.gameObject.GetComponent<IDamageable>();
                AttackDetail attackDetail = new AttackDetail();
                attackDetail.Direction = _direction;
                damageable.TakeDamage(attackDetail);
            }
            
        }
    }
}
